14.7 並行スイープ
スイープフェーズの並列化は以下のどちらか(どちらかって,下は上も含むんじゃないの?)
ヒープを連続するブロックに静的に分割する
細かく分割しておき,スレッドがブロックを獲得しては,スイープしてフリーリストにつなぐ
これらのような単純な戦略ではフリーリストがボトルネックになりGCが直列化
現実にはプロセッサ毎にフリーリストを持ち,隔離フィット割付を用いることが多い
ローカルのフリーリストへの連結はあまり気にしなくて良い
隔離フィット割り付けは,サイズクラスの分,負荷分散が図れるという意味で言及してるのかな?
異なるスレッドが別のサイズクラスへ連結するのは別に困らんやろという意味で
よって問題は次のように簡約化される:
「完全に空になったブロックをどのようにグローバルなブロックアロケータに返すか?」
遅延スイープ (ref 2.5 節) を用いる場合,ミューテータスレッドの割り付け速度に応じて負荷分散できる
復習:遅延スイープは,スイープをアロケータの仕事にすることで,回収コストを均すというアイデア
遅延スイープで問題になる部分は,完全に空のブロックを見つけて,ブロックアロケータに返す部分
Endo らは各スレッドにある程度の連続したブロックを割り付けるようにした
スイープを行うスレッド(= ミューテータスレッド = アロケータスレッド)がローカルに処理できるようにするため
ブロックが完全に空かどうかの判定が容易にできる
空のブロックは整列して互いに結合し,ローカルな空きブロックリストに追加
部分的に使用中のブロックは,後にミューテータスレッド(=スイープスレッド)が遅延スイープできるように(スレッド)ローカルな再利用リスト(回収リスト?)に追加
プロセッサ(-> スレッド?)は自分の仕事を終えると,ローカルな空きブロックのリストをグローバルのリストに結合
ローカルな再利用リストとグローバルなブロック(=スレッド全部で共有しているメモリ上にある)のプールがともに枯渇したら?
他のスレッドからブロックを盗むのが1つの解決策
次にスイープするブロックの取得を同期させる必要がある
もともとそのブロックをもっているスレッドと盗むスレッドで競合が発生しうるので
ブロックの取得はブロック中にスロットを割り付けるのに比べ低頻度で競合はほぼ起こらないので同期のコストは小